#pragma once
#include<SDL3/SDL.h>

class temporal_smoother {
public:
	temporal_smoother(SDL_Window* window, SDL_Renderer* renderer);
	// 开始帧渲染
	void begin();
	// 结束帧渲染
	void end(float current_weight=0.7);
	// 析构函数：释放资源
	~temporal_smoother();

private:
	SDL_Window* m_window = nullptr;        // 窗口指针
	SDL_Renderer* m_renderer = nullptr;    // 渲染器指针
	int m_width = 0, m_height = 0;         // 窗口尺寸
	SDL_Texture* m_currentColor = nullptr; // 当前帧颜色纹理（离屏渲染目标）
	SDL_Texture* m_historyColor = nullptr; // 历史帧颜色纹理
	SDL_Texture* m_motionVectors = nullptr;// 运动矢量纹理（简化）
	bool m_isFirstFrame = true;            // 是否为第一帧（无历史数据）
};

temporal_smoother::temporal_smoother(SDL_Window* window, SDL_Renderer* renderer)
	: m_window(window), m_renderer(renderer) {
	SDL_GetWindowSize(m_window, &m_width, &m_height);
	// 统一使用窗口原始尺寸作为目标纹理尺寸（高质量）
	int targetW = m_width;
	int targetH = m_height;

	m_currentColor = SDL_CreateTexture(
	                     m_renderer,
	                     SDL_PIXELFORMAT_RGBA32,
	                     SDL_TEXTUREACCESS_TARGET,
	                     targetW, targetH
	                 );
	if (!m_currentColor) {
		SDL_LogError(SDL_LOG_CATEGORY_RENDER, "创建当前帧纹理失败: %s", SDL_GetError());
		return;
	}

	m_historyColor = SDL_CreateTexture(
	                     m_renderer,
	                     SDL_PIXELFORMAT_RGBA32,
	                     SDL_TEXTUREACCESS_TARGET,
	                     targetW, targetH
	                 );
	if (!m_historyColor) {
		SDL_LogError(SDL_LOG_CATEGORY_RENDER, "创建历史帧纹理失败: %s", SDL_GetError());
		SDL_DestroyTexture(m_currentColor);
		return;
	}

	m_motionVectors = SDL_CreateTexture(
	                      m_renderer,
	                      SDL_PIXELFORMAT_RGB24,
	                      SDL_TEXTUREACCESS_TARGET,
	                      targetW, targetH
	                  );
	if (!m_motionVectors) {
		SDL_LogError(SDL_LOG_CATEGORY_RENDER, "创建运动矢量纹理失败: %s", SDL_GetError());
		SDL_DestroyTexture(m_currentColor);
		SDL_DestroyTexture(m_historyColor);
		return;
	}
	SDL_SetRenderTarget(m_renderer, m_historyColor);
	SDL_SetRenderTarget(m_renderer, nullptr);
}

void temporal_smoother::begin() {
	if (!m_currentColor) return;
	SDL_SetRenderTarget(m_renderer, m_currentColor);
}

void temporal_smoother::end(float current_weight) {
	if (!m_currentColor || !m_historyColor) return;
	float texW, texH;
	SDL_GetTextureSize(m_currentColor,  &texW, &texH);
	SDL_SetRenderTarget(m_renderer, nullptr);
	if (m_isFirstFrame) {
		SDL_FRect dest = {0, 0, (float)m_width, (float)m_height};
		SDL_RenderTexture(m_renderer, m_currentColor, nullptr, &dest);
		SDL_SetRenderTarget(m_renderer, m_historyColor);
		SDL_RenderTexture(m_renderer, m_currentColor, nullptr, nullptr);
		SDL_SetRenderTarget(m_renderer, nullptr);

		m_isFirstFrame = false;
	} else {
		float currentWeight = current_weight;
		float historyWeight = 1.0f - currentWeight;
		SDL_Texture* blended = SDL_CreateTexture(
		                           m_renderer,
		                           SDL_PIXELFORMAT_RGBA32,
		                           SDL_TEXTUREACCESS_TARGET,
		                           texW, texH
		                       );
		if (!blended) {
			SDL_LogError(SDL_LOG_CATEGORY_RENDER, "创建混合纹理失败: %s", SDL_GetError());
			return;
		}
		SDL_SetRenderTarget(m_renderer, blended);
		SDL_SetTextureAlphaMod(m_historyColor, (Uint8)(historyWeight * 255));
		SDL_RenderTexture(m_renderer, m_historyColor, nullptr, nullptr);
		SDL_SetTextureAlphaMod(m_currentColor, (Uint8)(currentWeight * 255));
		SDL_RenderTexture(m_renderer, m_currentColor, nullptr, nullptr);
		SDL_SetTextureAlphaMod(m_historyColor, 255);
		SDL_SetTextureAlphaMod(m_currentColor, 255);
		SDL_SetRenderTarget(m_renderer, nullptr);
		SDL_FRect dest = {0, 0, (float)m_width, (float)m_height};
		SDL_RenderTexture(m_renderer, blended, nullptr, &dest);
		SDL_SetRenderTarget(m_renderer, m_historyColor);
		SDL_RenderTexture(m_renderer, blended, nullptr, nullptr);
		SDL_DestroyTexture(blended);
	}
	SDL_RenderPresent(m_renderer);
}

temporal_smoother::~temporal_smoother() {
	SDL_DestroyTexture(m_motionVectors);
	SDL_DestroyTexture(m_currentColor);
	SDL_DestroyTexture(m_historyColor);
}
